﻿package com.sakura;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

//本文用UTF-8格式
public class sendEmailTest3 {
	public static void main(String[] args) throws Exception{
		Properties props=new Properties();//实例化一个Properties对象
		props.setProperty("mail.smtp.auth", "true");//设置是否校验.此处为true
		props.setProperty("mail.transport.protocol", "smtp");//设置传输协议
		props.setProperty("mail.host", "smtp.163.com");//设置smtp服务器.此处为163邮箱的smtp服务器。
		Session session=Session.getInstance(props,									//通过Session的静态方法getInstance传入上面的那个Properties对象
				new Authenticator() {												//从而获取一个session对象。
					protected PasswordAuthentication getPasswordAuthentication(){	//此处使用的是一种模式，叫策略模式。把一段能实现具体功能的代码
						return new PasswordAuthentication("13072368672@163.com","maozhi2764147");	//封装到一个对象里面，调用对象的函数即等于调用了那一段代码
					}
				}
		);
		//如果不用上面的这种方法实例化session对象，也可以直接通过getInstance方法获取一个session对象。如：Session session=Session.getInstance(pros);
		//不过需要在下面实例化Transport对象。并且设置它的connect方法，传入邮箱账号和密码，如下：
		//Transport transport=session.getTransport();						//通过session的getTransport()方法获得Transport对象
		//transport.connect("smtp.163.com", 25, "10086", "123456");	//打开连接        参数信息：1.smtp服务器 2.端口号 3.用户名 4.密码
		
		session.setDebug(true);//设置输出debug信息。true为输出
		
		Message msg=new MimeMessage(session);//传入一个session对象，实例化一个Message对象，mes相当于一个邮件
		msg.setSubject("附件图片HTML测试");	//设置邮件标题
		msg.setFrom(new InternetAddress("13072368672@163.com"));//设置发送人的邮箱
		
		//第一个参数为设置收件人类型， 1.收件人格式TO是正常收件人 BCC暗送 CC抄送 2.收件人邮箱 此处是正常收件人 .第二个参数是设置收件人的邮箱，如果有中文，需要通过MimeUtility的encodeText进行编码
		msg.setRecipient(RecipientType.TO, new InternetAddress(MimeUtility.encodeText("一零零一零")+" <1184225309@qq.com>"));
		//如果想要群发，可以这样:用InternetAddress.parse方法，邮箱之间用逗号隔开，该方法会把你分开一个个邮箱。
		//msg.setRecipients(RecipientType.TO, InternetAddress.parse("10000@qq.com,10010@qq.com"));
		
		MimeMultipart msgMultipart=new MimeMultipart("mixed");//设置msgMultipart的关系， mixed混合关系，此处是把邮件分割成各个部分。附件部分和正文部分。用mixed混合模式。
		msg.setContent(msgMultipart);//把msg对象的内容，即邮件的内容设置为MimeMultipart对象。然后再处理补充MimeMultipart对象里面的内容即可。
		
		MimeBodyPart attch1=new MimeBodyPart();//实例化MimeBodyPart对象。此MimeBodyPart为附件1.用于实现附件1
		MimeBodyPart attch2=new MimeBodyPart();//实例化MimeBodyPart对象。此MimeBodyPart为附件2.用于实现附件2
		MimeBodyPart content=new MimeBodyPart();//实例化MimeBodyPart对象。此MimeBodyPart为正文内容.
		msgMultipart.addBodyPart(attch1);//把附件1MimeBodyPart对象加进MimeMultipart对象中。
		msgMultipart.addBodyPart(attch2);//把附件2MimeBodyPart对象加进MimeMultipart对象中。
		msgMultipart.addBodyPart(content);//把正文MimeBodyPart对象加进MimeMultipart对象中。MimeMultipart包含MimeBodyPart。MimeBodyPart里面也可以有MimeMultipart对象...以此类推。
		
		//此处处理附件1的MimeBodyPart对象信息。
		DataSource ds1=new FileDataSource("resource\\slogo.gif");//实例化一个数据源。此处是工程下面的resource文件夹里面的slogo.gif图片
		DataHandler dh1=new DataHandler(ds1);//实例化一个DataHandler对象来处理访问数据源
		attch1.setDataHandler(dh1);//给附件1的MimeBodyPart对象设置DataHandler设置文件名。
		attch1.setFileName("slogo.gif");//给附件1的MimeBodyPart对象设置文件名，此处没有设置的话，不能成为一个附件。
		
		//继续处理附件2的MimeBodyPart对象信息。解释同上。
		DataSource ds2=new FileDataSource("resource\\Java培训.txt");
		DataHandler dh2=new DataHandler(ds2);
		attch2.setDataHandler(dh2);
		attch2.setFileName(MimeUtility.encodeText("Java培训.txt"));//此处有中文，所以需要进行编码，否则会出现乱码。
		
		//1
		MimeMultipart bodyMultipart=new MimeMultipart("related");//设置bodyMultipart的关系， related关联关系，如果你的正文里面没有带有图片，那么此处到下面//1的部分可以去掉
		content.setContent(bodyMultipart);
		
		MimeBodyPart htmlPart=new MimeBodyPart();//实例化一个MimeBodyPart对象。这是MimeBodyPart为html文本
		MimeBodyPart gifPart=new MimeBodyPart();//实例化一个MimeBodyPart对象。这是MimeBodyPart为文本内嵌图片
		bodyMultipart.addBodyPart(htmlPart);//加入到bodyMultipart对象里面去。
		bodyMultipart.addBodyPart(gifPart);//同上
		
		DataSource gifDs=new FileDataSource("resource\\logo.gif");//同上附件注释
		DataHandler gifDh=new DataHandler(gifDs);
		gifPart.setDataHandler(gifDh);//此处为内嵌图片，可以不用设置文件名
		gifPart.setHeader("Content-ID", "<image>");//该处是给图片设置对应ID，从而在收邮件的时候可以正确显示图片。html文本处的图片src地址为\"cid:image\对应image
		//1
		//<img src=\"cid:image\">为图片链接。如果你的正文不需要图片，那么可以去掉该链接即可。同时把上面的//1 //1包括的代码去掉。把下面的htmlPart.setContent改成content.setContent即可
		htmlPart.setContent("<span style='color:red'>你好啊！看看这是什么东西</span><a href='http://www.itcast.cn' target＝_blank><img src=\"cid:image\"></a>", "text/html;charset=UTF-8");//设置编码格式UTF-8
		msg.saveChanges();//保存邮件，关键的一步
		
		Transport.send(msg);//此处用Transport的静态方法send发送邮件。里面包含了打开连接和关闭连接两个动作。
		
		//若不用静态方法也可以用下面的
		//Transport transport=session.getTransport();//通过session的getTransport()方法获得Transport对象
		//transport.connect("smtp.163.com", 25, "10086", "123456");//打开连接        参数信息：1.smtp服务器 2.端口号 3.用户名 4.密码   此处各种参数如果上面设置了，该处就不用设置了。
		//transport.sendMessage(msg, new Address[]{new InternetAddress("10010@qq.com")});//设置收件人邮箱并发送邮件，此处可以设置多个收件人，实例化多几个InternetAddress对象即可，如果上面设置了收件人此处也可以省略设置。
		//transport.close();//关闭连接
		
		//下面把改邮件弄成一个邮件文件。
//		OutputStream ops=new FileOutputStream("resource//demo3.eml");
//		msg.writeTo(ops);//通过msg对象的writeTo把数据写进demo3.eml文件
//		ops.close();//关闭输出流
	}
}
